import datetime
import os
from rest_framework.views import APIView
from travel_recommend import settings
from .serializers import User, UserModelSerializer, UserCommentsSerializer, UserComments
from common import response
from .utils import public_user_data
from common.my_pagination import MyPageNumberPagination
from rest_framework.decorators import api_view
from rest_framework_simplejwt.tokens import AccessToken
from rest_framework.permissions import AllowAny
import csv
import pandas as pd
from django.http.response import StreamingHttpResponse


class Register(APIView):
    permission_classes = [AllowAny]

    def post(self, request):
        request_data = request.data
        serializer = UserModelSerializer(data=request_data)
        if serializer.is_valid():
            serializer.save()
            return response.success_msg('注册成功')
        else:
            print(serializer.errors)
            return response.success_msg('注册失败')


class GetUserInfo(APIView):
    def get(self, request):
        try:
            user_id = request.GET.get('id', None)
            user = UserModelSerializer(User.objects.filter(id=user_id), many=True).data
            return response.success_data(user)
        except:
            return response.server_error('操作失败')


@api_view(['get'])
def get_login_user_info(request):
    user_id = request.session.get('user_id')
    print(user_id)
    return response.success_data([])


class LoginUserInfo(APIView):
    def get(self, request):
        try:
            user_id = request.session.get('user_id', None)
            user = UserModelSerializer(User.objects.get(id=user_id)).data
            return response.success_data(user)
        except:
            return response.server_error('操作失败')


class SelectUserPage(APIView):
    pg_class = MyPageNumberPagination

    def get(self, request):
        try:
            # 获取查询参数
            pageNum = request.GET.get('pageNum', 1)
            pageSize = request.GET.get('pageSize', 10)
            username = request.GET.get('username', None)
            name = request.GET.get('name', None)

            # 判断查询参数是否存在，存在则根据查询条件获取数据库数据
            if username and name:
                users = User.objects.filter(username__contains=username, name__contains=name)
            elif username:
                users = User.objects.filter(username__contains=username)
            elif name:
                users = User.objects.filter(name__contains=name)
            else:
                users = public_user_data.getAllUser()
            # 创建分页对象
            page = self.pg_class()
            # 在数据库中获取分页的数据
            page_list = page.paginate_queryset(users, request, view=self)
            # 对分页进行序列化
            ser = UserModelSerializer(instance=page_list, many=True)
            data = {
                'pageNum': int(pageNum),
                'pageSize': int(pageSize),
                'total': users.count(),
                'list': ser.data,
            }
            return response.success_data(data)
        except:
            return response.server_error('操作失败')


# 用户表的增删改查操作
class UserOperation(APIView):
    # post：添加用户
    def post(self, request):
        password = request.POST.get('password')
        if not password:
            request.data['password'] = '123'
        request_data = request.data
        serializer = UserModelSerializer(data=request_data)
        if serializer.is_valid():
            serializer.save()
            return response.success_msg('添加成功')
        else:
            print(serializer.errors)
            return response.success_msg('添加失败')

    # delete：删除单个用户
    def delete(self, request):
        try:
            user_id = request.data['userId']
            User.objects.get(id=user_id).delete()
            return response.success_msg("删除成功")
        except:
            return response.server_error('删除失败')

    # put：修改用户数据
    def put(self, request):
        try:
            # 取出用户id
            user_id = request.data['id']
            # 查询该用户数据
            db_user = User.objects.get(id=user_id)
            # 构建序列化对象，第一个为查询到数据库用户数据，第二个为前端传入要更新的用户数据
            serializer = UserModelSerializer(instance=db_user, data=request.data)
            # 数据校验
            if serializer.is_valid():
                serializer.save()
                return response.success_msg('修改成功')
            else:
                return response.server_error('修改失败')
        except:
            return response.server_error('修改失败')

    # get：获取指定用户的数据
    def get(self, request):
        try:
            # 取出用户id
            user_id = request.GET.get('userId', None)
            # 数据库查询
            user = UserModelSerializer(User.objects.get(id=user_id)).data
            # 拼接返回结果
            data = {
                'user': user
            }
            return response.success_data(data)
        except:
            return response.server_error('查询不到该用户数据')


# 批量删除用户
class DeleteBatchUser(APIView):
    def post(self, request):
        try:
            # 获取要删除的用户id数组
            ids = request.data['ids']
            if len(ids) <= 0:
                return response.success_msg("未传入数据")
            # 删除用户个数
            count = 0
            # 遍历id数组
            for id in ids:
                try:
                    User.objects.get(id=id).delete()
                    count += 1
                except:
                    return response.server_error('批量删除有误，已删除%s条数据' % count)
            return response.success_msg("批量删除成功，已删除%s条数据" % count)
        except:
            return response.server_error('批量删除失败')


class UploadAvatar(APIView):
    def post(self, request):
        file = request.FILES.get('avatar')
        if not file:
            return response.server_error(message="上传文件不能为空")
        new_file_name = datetime.datetime.now().strftime('%Y%m%d%H%M%S') + '-' + file.name
        file_path = os.path.join(settings.USER_AVATAR_ROOT, new_file_name)
        try:
            with open(file_path, 'wb') as f:
                for chunk in file.chunks():
                    f.write(chunk)
            return response.success_data_msg(f'{settings.USER_MEDIA_URL}' + new_file_name, "上传成功")
        except:
            return response.server_error("上传头像失败")


@api_view(['get'])
def parseToken(request):
    auth_header = request.META.get('HTTP_AUTHORIZATION', None)
    # 移除'Bearer '前缀，获取令牌
    token = auth_header.split(' ')[1]

    # 示例：使用RefreshToken验证token是否有效
    refresh = AccessToken(token=token)
    # 如果验证成功，可以获取用户或其他信息
    userId = refresh.payload.get('user_id')  # 假设你在payload中存储了user_id
    if userId:
        user = UserModelSerializer(User.objects.get(id=userId)).data
        return response.success_data(user)
    else:
        return response.un_auth_error("请先登录系统")


# 用户评论操作接口（增删改查）
class UserCommentsOperation(APIView):
    # 添加
    def post(self, request):
        id = request.POST.get('id', None)
        if id:
            UserComments.objects.get(id=id).delete()

        ser = UserCommentsSerializer(data=request.data)
        if ser.is_valid():
            ser.save()
            return response.success_msg("添加成功")
        else:
            return response.server_error("添加失败")

    def put(self, request):
        id = request.data['id']
        db_user_comment = UserComments.objects.get(id=id)
        ser = UserCommentsSerializer(instance=db_user_comment, data=request.data)
        if ser.is_valid():
            ser.save()
            return response.success_msg("添加成功")
        else:
            print(ser.errors)
            return response.server_error(ser.errors)


# 下载用户表数据
class DownLoadUser(APIView):
    def get(self, request):
        # 查询所有用户数据，生成为DataFrame对象，这样就可以取出字段值，组成csv文件的标题
        df = pd.DataFrame(list(User.objects.all().values()))
        del df['password']

        # 查询所有用户数据
        all_data = UserModelSerializer(User.objects.all(), many=True).data
        new_file_name = datetime.datetime.now().strftime('%Y%m%d%H%M%S') + '.csv'
        file_path = os.path.join(settings.FILES_MEDIA_ROOT, new_file_name)
        # 新建csv文件，写入标题
        with open(file_path, 'w', encoding='gbk') as f:
            writer = csv.writer(f, delimiter=',')
            writer.writerow(df)

        # 写入内容
        for row in all_data:
            user = []
            for title in df:
                user.append(row[title])
            with open(file_path, 'a', encoding='gbk') as f:
                writer = csv.writer(f, delimiter=',')
                writer.writerow(user)

        def file_iterator(file_name, chunk_size=512):
            with open(file_name) as f:
                while True:
                    c = f.read(chunk_size)
                    if c:
                        yield c
                    else:
                        break

        res = StreamingHttpResponse(file_iterator(file_path))
        # 以下两行是为让浏览器下载文件
        res['Content-Type'] = 'application/octet-stream'
        res['Content-Disposition'] = 'attachment;filename="{0}"'.format(new_file_name)
        return res


# 下载用户表格导入模版
class DownLoadTemplate(APIView):
    def get(self, request):
        def file_iterator(file_name, chunk_size=512):
            with open(file_name) as f:
                while True:
                    c = f.read(chunk_size)
                    if c:
                        yield c
                    else:
                        break

        file_name = 'user-template.csv'
        file_path = os.path.join(settings.FILES_MEDIA_ROOT, file_name)

        res = StreamingHttpResponse(file_iterator(file_path))
        # 以下两行是为让浏览器下载文件
        res['Content-Type'] = 'application/octet-stream'
        res['Content-Disposition'] = 'attachment;filename="{0}"'.format(file_name)
        return res


class UploadUser(APIView):
    def post(self, request):
        file = request.FILES.get('file')
        if not file:
            return response.server_error(message="上传文件不能为空")
        new_file_name = datetime.datetime.now().strftime('%Y%m%d%H%M%S') + '-' + file.name
        file_path = os.path.join(settings.FILES_MEDIA_ROOT, new_file_name)
        f = open(file_path, 'wb')
        for chunk in file.chunks():
            f.write(chunk)
        f.close()

        with open(file_path, 'r', encoding='gbk') as f:
            read = csv.reader(f)
            next(read)
            for user in read:
                try:
                    username = user[0]
                    password = '123'
                    name = user[1]
                    role = user[2]
                    age = int(user[3])
                    gender = user[4]
                    address = user[5]

                    User.objects.create(
                        username=username,
                        password=password,
                        name=name,
                        role=role,
                        age=age,
                        gender=gender,
                        address=address
                    )
                except:
                    continue

        return response.success_msg('上传成功')
